package com.SouthernWall_404.Age_Capitalism.common.Gui.Menu;

import com.SouthernWall_404.Age_Capitalism.common.API.Info.ClientStoreInfo;
import com.SouthernWall_404.Age_Capitalism.common.Init.ModMenuType;
import com.SouthernWall_404.Age_Capitalism.common.Merchant.StoreClientMerchant;
import com.SouthernWall_404.Age_Capitalism.common.Network.C2S.AddingMerchantPacket;
import com.SouthernWall_404.Age_Capitalism.common.Network.ModChannels;
import com.SouthernWall_404.Age_Capitalism.common.Network.S2C.MerchantServerPacket;
import com.SouthernWall_404.Age_Capitalism.common.World.Entity.StoreBlockEntity;
import net.minecraft.core.BlockPos;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.Container;
import net.minecraft.world.SimpleContainer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.MerchantContainer;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.trading.Merchant;
import net.minecraft.world.item.trading.MerchantOffer;
import net.minecraft.world.item.trading.MerchantOffers;


public class ModSettingMerchantMenu extends AbstractContainerMenu {

    private StoreBlockEntity storeBlockEntity;

    public StoreClientMerchant storeClientMerchant;


//    MerchantMenu
    protected static final int PAYMENT1_SLOT = 0;
    protected static final int PAYMENT2_SLOT = 1;
    protected static final int RESULT_SLOT = 2;
    private static final int INV_SLOT_START = 3;
    private static final int INV_SLOT_END = 30;
    private static final int USE_ROW_SLOT_START = 30;
    private static final int USE_ROW_SLOT_END = 39;
    private static final int SELLSLOT1_X = 136;
    private static final int SELLSLOT2_X = 162;
    private static final int BUYSLOT_X = 220;
    private static final int ROW_Y = 37;
    public Merchant trader;
    public Container tradeContainer;
    private int merchantLevel;
    private boolean showProgressBar;
    private boolean canRestock;
    public final int windowId;

    public ModSettingMerchantMenu(int p_40033_, Inventory p_40034_, FriendlyByteBuf byteBuf) {

//        this(p_40033_, p_40034_, new ClientSideMerchant(p_40034_.player),byteBuf.readBlockPos());
        this(p_40033_,
                p_40034_,
                new StoreClientMerchant(p_40034_.player)
        );

    }

    public ModSettingMerchantMenu(int i, Inventory inventory,Merchant merchant) {

        super(ModMenuType.MOD_SETTING_MERCHANT_MENU.get(),i);

        this.windowId=i;

        if (!inventory.player.level().isClientSide) {
            MerchantOffers offers = merchant.getOffers();
            if (!offers.isEmpty()) {
                // 获取经验值等属性（假设 merchant 是自定义类型）
                int xp = merchant.getVillagerXp();
                boolean showProgress = merchant.showProgressBar();
                boolean canRestock = merchant.canRestock();

                // 发送同步包给打开菜单的玩家
                ModChannels.sendToClient(
                        new MerchantServerPacket(containerId, offers, 1, xp, showProgress, canRestock),
                        (ServerPlayer) inventory.player
                );
            }
        }


        this.tradeContainer = new SimpleContainer(3);
        this.trader = merchant;

        if(merchant instanceof  StoreBlockEntity storeBlockEntity) {
            this.storeBlockEntity = (StoreBlockEntity) storeBlockEntity;


        }



        this.addSlot(new Slot(this.tradeContainer, 0, 136, 37));
        this.addSlot(new Slot(this.tradeContainer, 1, 162, 37));
        this.addSlot(new Slot(this.tradeContainer, 2, 220, 37));

        for(int $$3 = 0; $$3 < 3; ++$$3) {
            for(int $$4 = 0; $$4 < 9; ++$$4) {
                this.addSlot(new Slot(inventory, $$4 + $$3 * 9 + 9, 108 + $$4 * 18, 84 + $$3 * 18));
            }
        }

        for(int $$5 = 0; $$5 < 9; ++$$5) {
            this.addSlot(new Slot(inventory, $$5, 108 + $$5 * 18, 142));
        }

    }

    public StoreBlockEntity getStoreEntity()
    {
        return this.storeBlockEntity;
    }

    public void setShowProgressBar(boolean p_40049_) {
        this.showProgressBar = p_40049_;
    }

    public void slotsChanged(Container p_40040_) {
//        this.tradeContainer.updateSellItem();
        super.slotsChanged(p_40040_);
    }

    public boolean stillValid(Player p_40042_) {
        return this.trader.getTradingPlayer() == p_40042_;
    }

    public int getTraderXp() {
        return this.trader.getVillagerXp();
    }

    public int getFutureTraderXp() {
//        return this.tradeContainer.getFutureXp();
        return 0;
    }

    public void setXp(int p_40067_) {
        this.trader.overrideXp(p_40067_);
    }

    public int getTraderLevel() {
        return this.merchantLevel;
    }

    public void setMerchantLevel(int p_40070_) {
        this.merchantLevel = p_40070_;
    }

    public void setCanRestock(boolean p_40059_) {
        this.canRestock = p_40059_;
    }

    public boolean canRestock() {
        return this.canRestock;
    }

    public boolean canTakeItemForPickAll(ItemStack p_40044_, Slot p_40045_) {
        return false;
    }

    @Override
    public ItemStack quickMoveStack(Player player, int index) {
//        if (index == 2) { // 输出槽位
////            MerchantOffer activeOffer = this.tradeContainer.getActiveOffer();
//            if (activeOffer != null && !activeOffer.isOutOfStock()) {
//                // 在服务端执行交易
//                if (!player.level().isClientSide) {
//                    executeTrade((ServerPlayer) player, activeOffer);
//                }
//                // 防止原版逻辑重复执行
//                return ItemStack.EMPTY;
//            }
//
//
//        }
//        return this.getSlot(index).getItem();
//
//        return super.quickMoveStack(player, index);

        ItemStack output = ItemStack.EMPTY;//目标输出
        Slot currentSlot = (Slot)this.slots.get(index);//获取当前位置
        if (currentSlot != null && currentSlot.hasItem()) {
            ItemStack currentSlotItem = currentSlot.getItem();
            output = currentSlotItem.copy();
            if (index == 2) {//如果当前是输出结果栏
                if (!this.moveItemStackTo(currentSlotItem, 3, 39, true)) {
                    return ItemStack.EMPTY;
                }

                currentSlot.onQuickCraft(currentSlotItem, output);
                this.playTradeSound();
            } else if (index != 0 && index != 1) {
                if (index >= 3 && index < 30) {
                    if (!this.moveItemStackTo(currentSlotItem, 30, 39, false)) {
                        return ItemStack.EMPTY;
                    }
                } else if (index >= 30 && index < 39 && !this.moveItemStackTo(currentSlotItem, 3, 30, false)) {
                    return ItemStack.EMPTY;
                }
            } else if (!this.moveItemStackTo(currentSlotItem, 3, 39, false)) {
                return ItemStack.EMPTY;
            }

            if (currentSlotItem.isEmpty()) {
                currentSlot.setByPlayer(ItemStack.EMPTY);
            } else {
                currentSlot.setChanged();
            }

            if (currentSlotItem.getCount() == output.getCount()) {
                return ItemStack.EMPTY;
            }

            currentSlot.onTake(player, currentSlotItem);
        }
        return output;
    }
    //做好准备，可能要写网络包了！



    // 执行交易（关键修复）
    public void executeTrade(ServerPlayer player, MerchantOffer offer) {
        // 检查输入物品是否足够
        ItemStack costA = offer.getCostA();
        ItemStack costB = offer.getCostB();
        ItemStack giveA=this.getSlot(0).getItem();
        ItemStack giveB=this.getSlot(1).getItem();


        if(giveA.is(costA.getItem())&&giveB.is(costB.getItem()))
        {
            if(giveA.areShareTagsEqual(costA)&&giveB.areShareTagsEqual(costB))
            {
                while(giveA.getCount()>=costA.getCount()&&giveB.getCount()>=costB.getCount())
                {
                    giveA.shrink(costA.getCount());
                    giveB.shrink(costB.getCount());


                    // 给予输出物品
                    ItemStack result = offer.getResult().copy();
                    if (!player.getInventory().add(result)) {
                        player.drop(result, false);
                    }
                }


            }
        }
        // 更新交易状态
//        offer.increaseUses();
        storeBlockEntity.notifyTrade(offer);

        // 保存并同步数据
        storeBlockEntity.setChanged();
        storeBlockEntity.syncToClient();
    }


    public void setSelectionHint(int i) {
//        this.tradeContainer.setSelectionHint(i);
    }


    private void playTradeSound() {
        if (!this.trader.isClientSide()) {
            Entity $$0 = (Entity)this.trader;
            $$0.level().playLocalSound($$0.getX(), $$0.getY(), $$0.getZ(), this.trader.getNotifyTradeSound(), SoundSource.NEUTRAL, 1.0F, 1.0F, false);
        }

    }

    public void removed(Player p_40051_) {
        super.removed(p_40051_);
        this.trader.setTradingPlayer((Player)null);
        if (!this.trader.isClientSide()) {
            if (!p_40051_.isAlive() || p_40051_ instanceof ServerPlayer && ((ServerPlayer)p_40051_).hasDisconnected()) {
                ItemStack $$1 = this.tradeContainer.removeItemNoUpdate(0);
                if (!$$1.isEmpty()) {
                    p_40051_.drop($$1, false);
                }

                $$1 = this.tradeContainer.removeItemNoUpdate(1);
                if (!$$1.isEmpty()) {
                    p_40051_.drop($$1, false);
                }
            } else if (p_40051_ instanceof ServerPlayer) {
                p_40051_.getInventory().placeItemBackInInventory(this.tradeContainer.removeItemNoUpdate(0));
                p_40051_.getInventory().placeItemBackInInventory(this.tradeContainer.removeItemNoUpdate(1));
            }

        }
    }


    public void tryMoveItems(int p_40073_) {
        if (p_40073_ >= 0 && this.getOffers().size() > p_40073_) {
            ItemStack $$1 = this.tradeContainer.getItem(0);
            if (!$$1.isEmpty()) {
                if (!this.moveItemStackTo($$1, 3, 39, true)) {
                    return;
                }

                this.tradeContainer.setItem(0, $$1);
            }

            ItemStack $$2 = this.tradeContainer.getItem(1);
            if (!$$2.isEmpty()) {
                if (!this.moveItemStackTo($$2, 3, 39, true)) {
                    return;
                }

                this.tradeContainer.setItem(1, $$2);
            }

            if (this.tradeContainer.getItem(0).isEmpty() && this.tradeContainer.getItem(1).isEmpty()) {
                ItemStack $$3 = ((MerchantOffer)this.getOffers().get(p_40073_)).getCostA();
                this.moveFromInventoryToPaymentSlot(0, $$3);
                ItemStack $$4 = ((MerchantOffer)this.getOffers().get(p_40073_)).getCostB();

                this.moveFromInventoryToPaymentSlot(1, $$4);
            }

        }
    }

    private void moveFromInventoryToPaymentSlot(int p_40061_, ItemStack p_40062_) {
        if (!p_40062_.isEmpty()) {
            for(int $$2 = 3; $$2 < 39; ++$$2) {
                ItemStack $$3 = ((Slot)this.slots.get($$2)).getItem();
                if (!$$3.isEmpty() && ItemStack.isSameItemSameTags(p_40062_, $$3)) {
                    ItemStack $$4 = this.tradeContainer.getItem(p_40061_);
                    int $$5 = $$4.isEmpty() ? 0 : $$4.getCount();
                    int $$6 = Math.min(p_40062_.getMaxStackSize() - $$5, $$3.getCount());
                    ItemStack $$7 = $$3.copy();
                    int $$8 = $$5 + $$6;
                    $$3.shrink($$6);
                    $$7.setCount($$8);
                    this.tradeContainer.setItem(p_40061_, $$7);
                    if ($$8 >= p_40062_.getMaxStackSize()) {
                        break;
                    }
                }
            }
        }

    }

    public void setOffers(MerchantOffers p_40047_) {
        this.trader.overrideOffers(p_40047_);

        BlockPos blockPos=ClientStoreInfo.blockPosMap.get(this.windowId);
        if(blockPos!=null)
        {
            ModChannels.sendToServer(new AddingMerchantPacket(p_40047_,blockPos));
        }
        else if(this.trader instanceof StoreClientMerchant storeClientMerchant)
        {
            storeClientMerchant.getTradingPlayer().displayClientMessage(Component.literal("BlockPos不存在！"),true);
        }

        //把修改回传
    }

    public MerchantOffers getOffers() {
        return this.trader.getOffers();
    }

    public boolean showProgressBar() {
        return this.showProgressBar;
    }
}
